/*
 * Project:     My Project Work, Copyright (C) 2011
 * Created at:  07.08.2011
 */
package de.myprojectwork.view;

import de.myprojectwork.model.TodoTreeTableModel;
import de.myprojectwork.model.TodoTreeTableModel.TodoTreeTableNode;
import de.myprojectwork.model.dto.Todo;
import de.myprojectwork.presenter.TodoPresenter;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
import org.jdesktop.swingx.JXDatePicker;
import org.jdesktop.swingx.JXTreeTable;

/**
 *
 * @author Chris Holdschuh
 */
public class TodoViewImpl extends AbstractView<TodoPresenter> implements TodoView {
    
    private final Dimension SIZE = new Dimension(380, 300);
    
    private final String TOOLTIP_COLUMN_0 = "Drei Tage, oder weniger, bis erreichen des Zieldatums";
    private final String TOOLTIP_COLUMN_1 = "Aufgabenbeschreibung";
    private final String TOOLTIP_COLUMN_2 = "Fertig in %";
    private final String TOOLTIP_B_LINK = "Verknüpfung anlegen";
    private final String TOOLTIP_B_OK = "Speichern";
    private final String TOOLTIP_B_DELETE = "Löschen";
    
    private final String TEXT_B_LINK = "Link";
    private final String TEXT_B_OK = "OK";
    private final String TEXT_B_DELETE = "X";
    private final String TEXT_L_ZIELDATUM = "Zieldatum:";
    private final String TEXT_L_FERTIG = "Fertig:";
    private final String TEXT_L_PRIO = "Prio:";
    private final String TEXT_TF_TEXT = "Neuen Eintrag anlegen...";
    
    private boolean notifyChangeTodoFired = false;
    
    private JTextField          tfText;
    private JXTreeTable         tabTodos;
    
    private JLabel              lZieldatum;
    private JXDatePicker        tfZieldatum;
    
    private JLabel              lFertig;
    private JComboBox<Integer>  cobFertig;
    
    private JLabel              lPrio;
    private JSpinner            numPrio;
    
    private JButton             bLink;
    private JButton             bOk;
    private JButton             bDelete;
    
    private JPanel              pControls;

    public TodoViewImpl(TodoPresenter presenter) {
        super(presenter);
    }
    
    @Override
    public void initUi() {
        tfText = new JTextField(TEXT_TF_TEXT);
        tfText.setFont(new Font(null, 0, 14));
        tfText.addActionListener(new ActionOk());
        tfText.addMouseListener(new ActionClickText());
        tfText.addKeyListener(new ActionTypeText());
        
        lZieldatum = new JLabel(TEXT_L_ZIELDATUM);
        tfZieldatum = new JXDatePicker(new Date());
        
        lFertig = new JLabel(TEXT_L_FERTIG);
        Integer[] statusArray = {0,10,20,30,40,50,60,70,80,90,100};
        cobFertig = new JComboBox<>(statusArray);
        
        lPrio = new JLabel(TEXT_L_PRIO);
        numPrio = new JSpinner();

        bLink = new JButton(TEXT_B_LINK);
        bLink.setToolTipText(TOOLTIP_B_LINK);
        
        bOk = new JButton(TEXT_B_OK);
        bOk.addActionListener(new ActionOk());
        bOk.setToolTipText(TOOLTIP_B_OK);
        bOk.setBackground(Color.GREEN);
        
        bDelete = new JButton(TEXT_B_DELETE);
        bDelete.addActionListener(new ActionDelete());
        bDelete.setToolTipText(TOOLTIP_B_DELETE);
        bDelete.setBackground(Color.red);
        
        Todo dummy = new Todo();
        dummy.setId(-1);
        List<Todo> dummyList = new ArrayList<>();
        dummyList.add(dummy);
        tabTodos = new JXTreeTable(new TodoTreeTableModel(dummyList));
        tabTodos.setAutoCreateColumnsFromModel(false);
        tabTodos.getColumnExt(0).setMaxWidth(10);
        tabTodos.getColumnExt(0).setToolTipText(TOOLTIP_COLUMN_0);
        tabTodos.getColumnExt(1).setToolTipText(TOOLTIP_COLUMN_1);
        tabTodos.getColumnExt(2).setMaxWidth(35);
        tabTodos.getColumnExt(2).setToolTipText(TOOLTIP_COLUMN_2);
        tabTodos.packSelected();
        tabTodos.addMouseListener(new ActionTreeTable());
        
        pControls = new JPanel();
        
        // layout
        GridBagLayout layoutRoot = new GridBagLayout();
        setLayout(layoutRoot);
        GridBagLayout layoutControls = new GridBagLayout();
        GridBagLayout layoutControlsHelp_1 = new GridBagLayout();
        GridBagLayout layoutControlsHelp_2 = new GridBagLayout();
        
        JScrollPane scrollPaneTabTodos = new JScrollPane(tabTodos);
        scrollPaneTabTodos.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        pControls.setLayout(layoutControls);
        pControls.setVisible(false);
        JPanel pControlsHelp_1 = new JPanel(layoutControlsHelp_1);
        JPanel pControlsHelp_2 = new JPanel(layoutControlsHelp_2);
        
        add(this, layoutRoot, tfText,             0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.HORIZONTAL, GridBagConstraints.NORTH);
        add(this, layoutRoot, pControls,          0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.HORIZONTAL, GridBagConstraints.NORTH);
        add(this, layoutRoot, scrollPaneTabTodos, 0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.BOTH, GridBagConstraints.NORTH);
        
        add(pControls, layoutControls, lZieldatum,      0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE,       GridBagConstraints.WEST, new Insets(0, 5, 0, 10));
        add(pControls, layoutControls, tfZieldatum,     1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE,       GridBagConstraints.WEST);
        add(pControls, layoutControls, lFertig,         2, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NONE,       GridBagConstraints.EAST, new Insets(0, 0, 0, 10));
        add(pControls, layoutControls, cobFertig,       3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.HORIZONTAL, GridBagConstraints.EAST, new Insets(0, 0, 0, 5));
        add(pControls, layoutControls, lPrio,           0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NONE,       GridBagConstraints.WEST, new Insets(0, 5, 0, 0));
        add(pControls, layoutControls, pControlsHelp_1, 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST);
        add(pControls, layoutControls, pControlsHelp_2, 3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.HORIZONTAL, GridBagConstraints.EAST);
        
        add(pControlsHelp_1, layoutControlsHelp_1, numPrio, 0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.WEST);
        add(pControlsHelp_1, layoutControlsHelp_1, bLink,   1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.EAST);
        
        add(pControlsHelp_2, layoutControlsHelp_2, bDelete, 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.WEST);
        add(pControlsHelp_2, layoutControlsHelp_2, bOk,     1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE, GridBagConstraints.EAST, new Insets(0, 0, 0, 5));
        
        setBorder(BorderFactory.createLineBorder(Color.black));
        setSize(SIZE);
        setPreferredSize(SIZE);
        setMinimumSize(SIZE);
    }

    @Override
    public void setTodoList(List<Todo> list) {
        tabTodos.setTreeTableModel(new TodoTreeTableModel(list));
        
    }
    
    @Override
    public void setTodo(Todo todo) {
        if (todo != null) {
            tfText.setText(todo.getText());
            tfZieldatum.setDate(todo.getTargetDate());
            cobFertig.setSelectedItem(new Integer(todo.getStatusPercent()));
        }
    }

    @Override
    public void setMaxValuePrio(int max, int current) {
        numPrio.setModel(new SpinnerNumberModel(current, 1, max, 1));
    }
    
    @Override
    public void clearInput() {
        tfText.setText(TEXT_TF_TEXT);
        cobFertig.setSelectedItem(new Integer(0));
        tabTodos.clearSelection();
        tfZieldatum.setDate(new Date());
        pControls.setVisible(false);
        notifyChangeTodoFired = false;
    }
    
    private Todo getSelectedTodo() {
        Todo result = null;
        if (tabTodos.getSelectedRow() >= 0) {
            Object[] pathArray = tabTodos.getPathForRow(tabTodos.getSelectedRow()).getPath();
            result = ((TodoTreeTableNode)pathArray[pathArray.length-1]).getTodo(); // das letzte Objekt ist die gewählte Zeile
        }
        return result;
    }
    
    private class ActionOk implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            presenter.newTodo(tfText.getText(), tfZieldatum.getDate(), (int)cobFertig.getSelectedItem(), (int)numPrio.getValue(),getSelectedTodo());
        }
    }
    
    private class ActionDelete implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            presenter.deleteTodo();
        }
    }
    
    private class ActionTreeTable extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                presenter.editTodo(getSelectedTodo());
                tabTodos.clearSelection();
                pControls.setVisible(true);
            }
            presenter.notifySelectedTodo(getSelectedTodo());
            notifyChangeTodoFired = true;
        }
    }
    
    private class ActionClickText extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            if (!notifyChangeTodoFired) {
                tfText.setText(null);
                pControls.setVisible(true);
                presenter.notifySelectedTodo(getSelectedTodo());
                notifyChangeTodoFired = true;
            }
        }
    }
    
    private class ActionTypeText extends KeyAdapter {

        @Override
        public void keyTyped(KeyEvent e) {
            if (!notifyChangeTodoFired) {
                tfText.setText(null);
                pControls.setVisible(true);
                presenter.notifySelectedTodo(getSelectedTodo());
                notifyChangeTodoFired = true;
            }
        }
        
    }
}
